package com.gitee.jmash.rbac.utils;

import com.gitee.jmash.common.cache.SerialCache;
import com.gitee.jmash.common.grpc.auth.OAuth2Credentials;
import com.gitee.jmash.sms.client.SmsClient;
import jakarta.enterprise.inject.spi.CDI;
import java.util.Random;
import jmash.sms.protobuf.SmsProvider;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import jmash.sms.protobuf.EmailCaptchaReq;
import jmash.sms.protobuf.SmsCaptchaReq;
import org.eclipse.microprofile.config.Config;
import org.eclipse.microprofile.config.ConfigProvider;

/**
 * 验证码工具类
 * 
 * @author cgd
 * 2024/01/26
 */
public class VerifyCodeUtil {

  private static Log log = LogFactory.getLog(VerifyCodeUtil.class);

  private static String PERFIX = "verifycode:";

  /** 验证码缓存. */
  public static SerialCache getCache() {
    return CDI.current().select(SerialCache.class).get();
  }

  /** 验证输入验证码是否正确. */
  public static boolean validate(String name, String verifyCode) {
    if (getCache().containsKey(PERFIX + name)) {
      String code = (String) getCache().remove(PERFIX + name);
      return StringUtils.equals(verifyCode, code);
    }
    return false;
  }

  /** 未短信和邮件验证,创建验证码. */
  public static boolean createVerifyCode(String tenant, String name, int length, String product) {
    String verifyCode = generateVerifyCode(length);
    // 缓存10分钟.
    getCache().put(PERFIX + name, verifyCode, 10 * 60);
    log.debug(String.format(" %s 验证码 %s ", name, verifyCode));
    String accessToken = TokenUtil.createSysAccessToken(tenant);
    if (ValidateUtil.validatePhone(name)) {
      // 手机号
      SmsCaptchaReq sendCaptchaReq = SmsCaptchaReq.newBuilder().setTenant(tenant)
          .setCaptcha(verifyCode).setSmsSign(getSmsSign()).setConfigCode(getSmsConfigCode())
          .setProduct(product).setMobilePhone(name).setHasProvider(true)
          .setProvider(SmsProvider.Aliyun).build();
      SmsClient.getSmsBlockingStub().withCallCredentials(new OAuth2Credentials(accessToken))
          .sendSmsCaptcha(sendCaptchaReq);
    } else if (ValidateUtil.validateEmail(name)) {
      // 发送电子邮件.
      EmailCaptchaReq sendCaptchaReq = EmailCaptchaReq.newBuilder().setTenant(tenant)
          .setCaptcha(verifyCode).setEmail(name).build();
      SmsClient.getSmsBlockingStub().withCallCredentials(new OAuth2Credentials(accessToken))
          .sendEmailCaptcha(sendCaptchaReq);
    } else {
      String error = String.format("请输入合法手机号或电子邮箱地址! %s ", name);
      log.error(error);
      throw new RuntimeException(error);
    }
    return true;
  }

  /** 根据长度生成验证码. */
  public static String generateVerifyCode(int length) {
    String result = null;
    // 最小值
    int min = 0;
    // 最大值
    int max = 9;
    Random random = new Random();
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < length; i++) {
      int randomNumber = min + random.nextInt(max);
      sb.append(randomNumber);
    }
    result = sb.toString();
    return result;
  }

  /**
   * 获取短信签名.
   */
  public static String getSmsSign() {
    Config config = ConfigProvider.getConfig();
    return config.getValue("sms.sign", String.class);
  }

  /**
   * 获取短信应用配置编码.
   */
  public static String getSmsConfigCode() {
    Config config = ConfigProvider.getConfig();
    return config.getValue("sms.config.code", String.class);
  }

}
